package com.security.authority.voter;
import com.security.domain.authority.CommonUserDetails;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import java.util.Collection;
import java.util.Set;

/**
 *
 * @apiNote 如果匹配成功,投赞成票; 匹配失败,投中立票
 * @author 大忽悠
 * @create 2022/10/11 16:24
 */
public class AuthorityPatternVoter implements AccessDecisionVoter<Object> {
    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }

    /**
     * @param authentication 当前用户信息存放,包括用户具备的角色集合
     * @param object FilterInvocation或者MethodInvocation---可以获取到当前requestUri
     * @param attributes 访问当前url需要具备的角色集合
     * @return 投票结果
     */
    @Override
    public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
        Object principal = authentication.getPrincipal();
        if(!(principal instanceof CommonUserDetails)){
            return ACCESS_ABSTAIN;
        }
        CommonUserDetails commonUserDetails = (CommonUserDetails) principal;
        if(roleMatched(commonUserDetails.getUserRoles(),attributes)){
            return ACCESS_GRANTED;
        }
        return ACCESS_ABSTAIN;
    }

    /**
     * @param userRoles 当前用户具备的角色
     * @param urlRoles 访问当前url需要的角色
     * @return 是否匹配通过
     */
    private Boolean roleMatched(Set<String> userRoles, Collection<ConfigAttribute> urlRoles){
        for (ConfigAttribute urlRole : urlRoles) {
              if(userRoles.contains(urlRole.getAttribute())){
                  return Boolean.TRUE;
              }
        }
        return Boolean.FALSE;
    }
}
